﻿using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
using ZXing;
using ZXing.QrCode;

namespace QRCodeDemo
{
    public partial class Form1 : Form
    {
        private String mode = "";
        private SS_SSRLinkHandler linkHandler;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Create a toolTip
            ToolTip qrCodeImgTip = new ToolTip
            {
                // Set the period of time the tips remains visible
                AutoPopDelay = 2000,
                // Set the time that passes before tips appears
                InitialDelay = 100,
                // Set length of time that must transpire before tips show again when the pointer moves from one control to another
                ReshowDelay = 100,
                // Always show tips 
                ShowAlways = true
            };

            ToolTip btnTips = new ToolTip
            {
                AutoPopDelay = 2000,
                InitialDelay = 1000,
                ReshowDelay = 100,
                ShowAlways = true
            };

            qrCodeImgTip.SetToolTip(pbQRcode, "Double click to Save the image\r\nRight click to Copy to clipboard");
            btnTips.SetToolTip(btnDecode, "Deocode from file");
            btnTips.SetToolTip(btnDecodeFC, "Decode from clipboard");
            btnTips.SetToolTip(btnDecodeFU, "Decode from URL");
            btnTips.SetToolTip(btnEncode, "Encode text");
            btnTips.SetToolTip(btnEncodeFC, "Encode from clipboard");

            mode = "normal";
            linkHandler = new SS_SSRLinkHandler();
        }

        private void btnDecode_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog fileDlg = new OpenFileDialog();
                fileDlg.Title = "Open an image";
                fileDlg.Filter = "(*.jpg *.jpeg *.bmp *.png)|*.jpg;*.jpeg;*.bmp;*.png";
                fileDlg.RestoreDirectory = true;
                fileDlg.FilterIndex = 1;
                fileDlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                fileDlg.Multiselect = false;
                if (fileDlg.ShowDialog() == DialogResult.OK)
                {
                    Bitmap bitmap = new Bitmap(fileDlg.FileName);
                    pbQRcode.Image = bitmap;
                    Decode(bitmap);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnDecodeFC_Click(object sender, EventArgs e)
        {
            try
            {
                IDataObject data = Clipboard.GetDataObject(); // Get data from the clipboard
                if (data.GetDataPresent(typeof(Bitmap))) // Determines whether the data is a picture type
                {
                    Bitmap bitmap = (Bitmap)data.GetData(typeof(Bitmap)); // Save the image data in a bitmap
                    pbQRcode.Image = bitmap;
                    Decode(bitmap);
                }
                else
                {
                    MessageBox.Show("There is no image data in the clipboard!");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnDecodeFU_Click(object sender, EventArgs e)
        {
            try
            {
                Uri uri = new Uri(tbContent.Text);
                WebRequest request = WebRequest.Create(uri);
                WebResponse response = request.GetResponse();
                Stream stream = response.GetResponseStream();

                Bitmap bitmap = (Bitmap)Image.FromStream(stream);
                pbQRcode.Image = bitmap;
                Decode(bitmap);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnScanScreens_Click(object sender, EventArgs e)
        {

        }

        private void btnScanByCamera_Click(object sender, EventArgs e)
        {

        }

        private void Decode(Bitmap bitmap)
        {
            BarcodeReader reader = new BarcodeReader();
            reader.Options.CharacterSet = "UTF-8";
            reader.Options.TryHarder = true;
            Result result = reader.Decode(bitmap);
            if (result != null)
            {
                tbContent.Text = result.Text;
                if (result.Text == "Content...")
                {
                    tbContent_TextChanged(this, null);
                }
                if(mode == "SS/SSR")
                {
                    linkHandler.Link = result.Text;
                    linkHandler.GetParams();
                    tbContent.Text = linkHandler.DecodedLink;
                }
            }
            else
            {
                MessageBox.Show("Decoding failed!");
            }
        }

        private void btnEncode_Click(object sender, EventArgs e)
        {
            try
            {
                if(tbContent.Text.Length > 0 && tbContent.ForeColor == Color.Black)
                {
                    Encode(tbContent.Text);
                }
                else
                {
                    MessageBox.Show("Please input some texts");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        
        private void btnEncodeFC_Click(object sender, EventArgs e)
        {
            String text = Clipboard.GetText();
            tbContent.Text = text;
            if (text == "Content...")
            {
                tbContent_TextChanged(this, null);
            }
            if (!String.IsNullOrEmpty(text))
            {
                Encode(text);
            }
            else
            {
                MessageBox.Show("There is no text in the clipboard!");
            }
        }
        
        private void Encode(String text)
        {
            QrCodeEncodingOptions options = new QrCodeEncodingOptions();
            options.CharacterSet = "UTF-8";
            options.Width = 300;
            options.Height = 300;
            options.Margin = 1;
            BarcodeWriter writer = new BarcodeWriter();
            writer.Format = BarcodeFormat.QR_CODE;
            writer.Options = options;

            Bitmap bitmap = writer.Write(text);
            if(bitmap != null)
            {
                pbQRcode.Image = bitmap;
            }
            else 
            {
                MessageBox.Show("Encoding failed");
            }
        }

        private void tbContent_Leave(object sender, EventArgs e)
        {
            if (tbContent.Text.Length == 0)
            {
                tbContent.Text = "Content...";
                tbContent.ForeColor = Color.Silver;
            }
        }

        private void tbContent_Enter(object sender, EventArgs e)
        {
            if (tbContent.ForeColor == Color.Silver)
            {
                tbContent.Clear();
                tbContent.ForeColor = Color.Black;
            }
        }

        private void tbContent_TextChanged(object sender, EventArgs e)
        {
            if (tbContent.ForeColor != Color.Black)
            {
                tbContent.ForeColor = Color.Black;
            }
        }
        
        private void pbQRcode_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && e.Clicks == 2)
            {
                try
                {
                    SaveFileDialog saveFileDialog = new SaveFileDialog();
                    saveFileDialog.Title = "Save File";
                    saveFileDialog.Filter = "(*.jpg)|*.jpg";
                    saveFileDialog.FilterIndex = 1;
                    saveFileDialog.RestoreDirectory = true;
                    if (saveFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        string localFilePath = saveFileDialog.FileName.ToString();
                        FileStream fs = (FileStream)saveFileDialog.OpenFile();
                        pbQRcode.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
                        fs.Close();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void pbQRcode_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Clipboard.SetImage(pbQRcode.Image);
                lbNotice.Visible = true;
                timer.Start();
            }
        }
        
        private void timer_Tick(object sender, EventArgs e)
        {
            timer.Stop();
            timer.Enabled = false;
            if(lbNotice.Visible)
            {
                lbNotice.Visible = false;
            }
        }

        private void radioNormal_CheckedChanged(object sender, EventArgs e)
        {
            mode = "normal";
            btnEncode.Enabled = true;
            btnEncodeFC.Enabled = true;
        }

        private void radioSS_CheckedChanged(object sender, EventArgs e)
        {
            mode = "SS/SSR";
            btnEncode.Enabled = false;
            btnEncodeFC.Enabled = false;
        }
        
        // TODO Generate ss/ssr QR Code
        // TODO Scan QR code on screen | Scan by camera
        // TODO Pack up dlls
        // TODO Set progrees bar for downloading image form url
    }
}
